package com.fdb.efp.nls.service.impl.sx;

import static com.fdb.basic.sequence.service.DefaultPatternDescriptor.DAY;
import static com.fdb.basic.sequence.service.DefaultPatternDescriptor.MONTH;
import static com.fdb.basic.sequence.service.DefaultPatternDescriptor.SEQ;
import static com.fdb.basic.sequence.service.DefaultPatternDescriptor.YEAR_4;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Objects;

import com.fdb.efp.nls.service.facade.sx.NlsCreditInfoService;
import com.fdb.efp.nls.service.vo.queue.NlsProcessBizVO;
import com.fdb.efp.nls.service.vo.sx.NlsCreditInfoVO;
import com.fdb.basic.framework.core.constant.BaseConstant;
import com.fdb.basic.framework.core.util.TimeUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.fdb.basic.framework.core.exception.BizException;
import com.fdb.basic.framework.core.util.DateUtility;
import com.fdb.basic.framework.core.util.SpringContextUtils;
import com.fdb.basic.framework.core.util.StringUtil;
import com.fdb.basic.sequence.service.DefaultPatternDescriptor;
import com.fdb.basic.sequence.service.PatternDescriptor;
import com.fdb.basic.sequence.service.facade.PatternedLimitableSeqService;
import com.fdb.efp.nls.common.ConsoleConstant;
import com.fdb.efp.nls.service.facade.PrdInfoService;
import com.fdb.efp.nls.service.vo.PrdInfoVO;
import com.fdb.efp.esb.common.constant.MsLoanConstant;
import com.fdb.efp.esb.service.bo.req.sx.CreditBasicInfo;
import com.fdb.efp.esb.service.bo.req.sx.CreditExpanding;
import com.fdb.efp.esb.service.bo.req.sx.CreditMessage;
import com.fdb.efp.esb.service.bo.req.sx.CreditReq;
import com.fdb.efp.esb.service.bo.resp.sx.CreditResp;
import com.fdb.efp.esb.service.facade.sx.CreditService;
import com.fdb.efp.limit.service.facade.LmtPrdContService;
import com.fdb.efp.limit.service.vo.LmtPrdContVO;

/**
 * 授信生成额度接口
  * @author heyingfeng
  * @since 2019年3月12日 下午8:04:48
  * @version 1.0
 */
@Service("creditLmtService")
public class CreditLmtServiceImpl extends CreditSoltServiceImpl {

	private static Logger logger = LoggerFactory.getLogger(CreditLmtServiceImpl.class);
	private static final PatternDescriptor pattern = DefaultPatternDescriptor.of("lmt" + YEAR_4 + MONTH + DAY + SEQ, 8);
	private static final String other = "Other";
	private   String expire_date = "2099-12-31";
	
	@Autowired
	@Qualifier("lmtPrdContService")
	private LmtPrdContService lmtPrdContService;

	@Autowired
	@Qualifier("nlsCreditInfoService")
	private NlsCreditInfoService nlsCreditInfoService;
	
	@Autowired
	@Qualifier("creditService")
	private CreditService creditService;
	
	@Autowired
	@Qualifier("prdInfoService")
	private PrdInfoService prdInfoService;

	@Override
	protected void doExecute(NlsProcessBizVO nlsProcessBizVo, NlsCreditInfoVO nlsCreditInfoVO) throws Exception {
		String applySeq = nlsProcessBizVo.getApplySeq();// 流水号
		logger.info("授信申请审核通知接口，流水号:" + applySeq);
		try {
			Objects.requireNonNull(nlsCreditInfoVO);// 网贷申请信息不能为空
			
			//获取产品
			PrdInfoVO prdInfoVo = new PrdInfoVO();
			prdInfoVo.setPrdId(nlsCreditInfoVO.getPrdId());
			prdInfoVo = prdInfoService.queryByPk(prdInfoVo);
			
			LmtPrdContVO lmtPrdContVO = new LmtPrdContVO();
			lmtPrdContVO.setCertType(nlsCreditInfoVO.getCertType());//证件类型
			lmtPrdContVO.setCertCode(nlsCreditInfoVO.getCertCode());//证件号
			lmtPrdContVO.setPrdCode(nlsCreditInfoVO.getPrdCode());
			List<LmtPrdContVO> lmtList = lmtPrdContService.queryLmtPrdList(lmtPrdContVO);
			/**额度管控，将原生效的授信额度置为失效*/
			if(lmtList != null && lmtList.size() > 0) {//如果有数据，则设置所有数据状态为失效
				lmtPrdContVO.setLmtStatus(ConsoleConstant.LIMIT_STS_03);
				int num0 = lmtPrdContService.updateByPk(lmtPrdContVO);
				if (num0 == -1) {
					throw new BizException("更新额度协议表异常!");
				}
			}
			lmtPrdContVO.setLmtContNo(generateLmtContNo());//流水号
			lmtPrdContVO.setLmtApplySeq(nlsCreditInfoVO.getLmtApplySeq());//授信流水号
			lmtPrdContVO.setCusId(nlsCreditInfoVO.getCusId());//客户id
			lmtPrdContVO.setCusName(nlsCreditInfoVO.getCusName());//客户名称
			lmtPrdContVO.setCertType(nlsCreditInfoVO.getCertType());//证件类型
			lmtPrdContVO.setCertCode(nlsCreditInfoVO.getCertCode());//证件号
			lmtPrdContVO.setChannelNo(nlsCreditInfoVO.getChannelNo());//渠道号
			lmtPrdContVO.setPrdId(nlsCreditInfoVO.getPrdId());//产品id
			lmtPrdContVO.setPrdCode(nlsCreditInfoVO.getPrdCode());//产品代码
			lmtPrdContVO.setPrdName(nlsCreditInfoVO.getPrdName());//产品名称
			lmtPrdContVO.setLmtAmt(nlsCreditInfoVO.getApproveAmt());//审批金额
			lmtPrdContVO.setCyclicFlg(nlsCreditInfoVO.getCyclicFlg() == null ? "" : nlsCreditInfoVO.getCyclicFlg());//是否循环
			lmtPrdContVO.setCurrencyType(nlsCreditInfoVO.getCurrencyType());//币种
			lmtPrdContVO.setTerm(new BigDecimal(nlsCreditInfoVO.getApplyTerm()));//期限
			lmtPrdContVO.setTermType(nlsCreditInfoVO.getTermType());//期限类型
			lmtPrdContVO.setRateY(StringUtil.isNullorBank(nlsCreditInfoVO.getApplyRateY()+"") ? BigDecimal.ZERO : nlsCreditInfoVO.getApplyRateY());//利率(年)
			lmtPrdContVO.setAssureMeansMain(StringUtil.isNullorBank(nlsCreditInfoVO.getAssureMeansMain()) ? "" : nlsCreditInfoVO.getAssureMeansMain());//担保方式
			lmtPrdContVO.setAssureMeans2(StringUtil.isNullorBank(nlsCreditInfoVO.getAssureMeans2()) ? "" : nlsCreditInfoVO.getAssureMeans2());//担保方式2
			lmtPrdContVO.setAssureMeans3(StringUtil.isNullorBank(nlsCreditInfoVO.getAssureMeans3()) ? "" : nlsCreditInfoVO.getAssureMeans3());//担保方式3
			lmtPrdContVO.setRepaymentMode(StringUtil.isNullorBank(nlsCreditInfoVO.getRepaymentMode()) ? "" : nlsCreditInfoVO.getRepaymentMode());//还款方式
			lmtPrdContVO.setRepaymentPeriod(StringUtil.isNullorBank(nlsCreditInfoVO.getRepaymentPeriod()) ? BigDecimal.ZERO : new BigDecimal(nlsCreditInfoVO.getRepaymentPeriod()));//还款周期
			lmtPrdContVO.setRepaymentPeriodType(StringUtil.isNullorBank(nlsCreditInfoVO.getRepaymentPeriodType()) ? "" : nlsCreditInfoVO.getRepaymentPeriodType());//还款周期单位
			lmtPrdContVO.setRepaymentDay(StringUtil.isNullorBank(nlsCreditInfoVO.getRepaymentDay()) ? BigDecimal.ZERO : new BigDecimal(nlsCreditInfoVO.getRepaymentDay()));//还款日
			lmtPrdContVO.setRepaymentDayType(StringUtil.isNullorBank(nlsCreditInfoVO.getRepaymentDayType()) ? "" : nlsCreditInfoVO.getRepaymentDayType());//还款日类型
			lmtPrdContVO.setLoanUse(StringUtil.isNullorBank(nlsCreditInfoVO.getLoanUseType()) ? "" : nlsCreditInfoVO.getLoanUseType());//贷款用途
			lmtPrdContVO.setLmtStatus(ConsoleConstant.LIMIT_STS_02);//额度状态
			lmtPrdContVO.setStartDate(nlsCreditInfoVO.getApplyDate());//起始日期
			/**额度管控 修改到期日期限 modify by chenxuan*/
			int term_ = Integer.valueOf(nlsCreditInfoVO.getApplyTerm() == null ? "0":nlsCreditInfoVO.getApplyTerm());
			if(BaseConstant.TERM_TYPE_DAY.equals(nlsCreditInfoVO.getTermType())) {
				expire_date = TimeUtil.addDay(nlsCreditInfoVO.getApplyDate(), term_);
			} else if(BaseConstant.TERM_TYPE_MONTH.equals(nlsCreditInfoVO.getTermType())) {
				expire_date = TimeUtil.addMonth(nlsCreditInfoVO.getApplyDate(), term_);
			} else if(BaseConstant.TERM_TYPE_YEAR.equals(nlsCreditInfoVO.getTermType())) {
				expire_date = TimeUtil.addYear(nlsCreditInfoVO.getApplyDate(), term_);
			}
			lmtPrdContVO.setExpireDate(expire_date);//到期日期默认
			lmtPrdContVO.setSignDate(nlsCreditInfoVO.getApplyDate());//签订日期
			lmtPrdContVO.setValidDays(prdInfoVo.getCreditTerm());//授信批复有效期
			lmtPrdContVO.setCreateTime(DateUtility.getCurrAppDateTimeString());//创建时间
			lmtPrdContVO.setCreateUser("admin");//创建人
			lmtPrdContVO.setLastUpdateTime(DateUtility.getCurrAppDateTimeString());//最后更新时间
			lmtPrdContVO.setLastUpdateUser("admin");//最后更新人
			int num1 = lmtPrdContService.insertLmtPrdCont(lmtPrdContVO);
			if (num1 == -1) {
				throw new BizException("插入额度协议表异常!");
			}
			nlsCreditInfoVO.setApproveRateY(nlsCreditInfoVO.getApplyRateY());//批复执行年利率
			int num2 = nlsCreditInfoService.updateByPk(nlsCreditInfoVO);
			if (num2 == -1) {
				throw new BizException("更新批复执行年利率异常!");
			}
			this.creditLmtBack(nlsCreditInfoVO);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("授信审核通知出现异常：" + e.getMessage());
			/**设置百度原因说明**/
			nlsCreditInfoVO.setBdReasonCode(MsLoanConstant.ReasonCodeMap.get(other));
			nlsCreditInfoVO.setBdReasonMsg(MsLoanConstant.ReasonMsgMap.get(other));
			nlsProcessBizVo.setExceptionFlag(true);
			nlsProcessBizVo.setExceptionMsg(e);
		}
	}
	
	private void creditLmtBack(NlsCreditInfoVO nlsCreditInfoVO) {
		try {
			//回调接口
			logger.info("授信申请审核通知接口，流水号:" + nlsCreditInfoVO.getLmtApplySeq());
			Objects.requireNonNull(nlsCreditInfoVO);// 网贷申请信息不能为空
			CreditReq creditReq = new CreditReq();
			CreditMessage creditMessage = new CreditMessage();
			CreditBasicInfo creditBasicInfo = new CreditBasicInfo();
			CreditExpanding creditExpanding = new CreditExpanding();
			creditReq.setRqsFlg(nlsCreditInfoVO.getBdReqSn());//请求方需要保证永远唯一 响应方据此判断是否重复请求
			creditReq.setProdCd(nlsCreditInfoVO.getPrdCode());//产品代码
			creditReq.setRetCd(MsLoanConstant.RetCodeEnum.SUCCESS.VALUE);
			creditReq.setTxnMd("async");//交易模式
			creditReq.setRepeatRqsBss(nlsCreditInfoVO.getBdReqSn());//重复请求依据
			/** Message	业务数据 start */
			creditMessage.setSessionId(nlsCreditInfoVO.getLmtApplySeq());// 交易流水号
			creditMessage.setEvTp("apply");//事务类型
			creditMessage.setEvID(nlsCreditInfoVO.getBdTransactionId());//事务ID
			creditMessage.setRqsTmstmp(TimeUtil.getSeconTimestamp(new Date()));//时间戳
			/** BasicInfo	基本信息 start */
			creditBasicInfo.setIDCertNo(nlsCreditInfoVO.getCertCode());//身份证号
			creditBasicInfo.setBankCardNo(nlsCreditInfoVO.getRecvAccount());//银行卡号
			creditBasicInfo.setCustNm(nlsCreditInfoVO.getCusName());//客户姓名
			creditBasicInfo.setMblNo(nlsCreditInfoVO.getIndivMobile());//手机号码
			/** BasicInfo	基本信息 end */
			/** Expanding	定制域 start */
			creditExpanding.setCrdtLmt(nlsCreditInfoVO.getApplyAmt()+"");	//授信额度
			creditExpanding.setCrdtDt(nlsCreditInfoVO.getApplyTerm());	//授信有效期
			creditExpanding.setInstRsnCd(nlsCreditInfoVO.getBdReasonCode());	//机构原因码
			creditExpanding.setInstRsnCdRmk(nlsCreditInfoVO.getBdReasonMsg());	//机构原因码说明
			creditExpanding.setInstPolcyCd(MsLoanConstant.RisCodeEnum.SUCCESS.VALUE);	//机构策略码
			/** Expanding	定制域 end */
			creditMessage.setBasicInfo(creditBasicInfo);
			creditMessage.setExpanding(creditExpanding);
			creditReq.setMessage(creditMessage);
			CreditResp creditResp = creditService.creditNotify(creditReq);// 发送请求
			if (!MsLoanConstant.RetCodeEnum.SUCCESS.VALUE.equals(creditResp.getRetCd()) || 
					!"E1001".equals(creditResp.getRetCd())) {// 0：请求成功，其他编码均代表失败
				logger.error("调用授信审批结果消费接口返回信息出错");
			}else {
				logger.error("调用授信审批结果消费接口返回信息成功");
			}
		} catch (Exception e) {
			logger.error("调用授信审批结果回调出现异常：" + e.getMessage());
		}
	}
	
	/* 生成LMT系统的交易流水号(LmtContNo) */
	public String generateLmtContNo(){
		PatternedLimitableSeqService sequenceService = SpringContextUtils.getBean(PatternedLimitableSeqService.class);
		return sequenceService.getPatternedSequence("LMT", pattern);
	}

}
